const GeoHash = require("../../library/geohash.js");
const crypto = require("crypto");

module.exports = function(lab) {
    return {

        @getStore : function ({ouid, store_number, store_id}) {

            if (!store_number && !store_id) {
                throw @lab.errors.invalid_parameters;
            }

            var storeQuery = {};
            if (ouid) {
                storeQuery.ouid = ouid;
            }

            if (store_id){
                storeQuery.id = store_id;
            }

            if (store_number) {
                storeQuery.store_number = store_number;
            }
            return lab.find("slime_stores",storeQuery).then(function (store) {
                if (store) {
                    this.next(store);
                } else {
                    throw @lab.errors.invalid_parameters;
                }
            })
        },

        /**
         * @apiDefine TypeDefineStore
         * @apiSuccess (Store) {String} id 门店Id
         * @apiSuccess (Store) {String} store_number 门店编码
         * @apiSuccess (Store) {String} store_name 门店名称
         * @apiSuccess (Store) {String} store_country 国家
         * @apiSuccess (Store) {String} store_province 省份
         * @apiSuccess (Store) {Number} store_city 城市
         * @apiSuccess (Store) {Number} store_district 区
         * @apiSuccess (Store) {Number} store_address 门店地址
         * @apiSuccess (Store) {String} store_longitude 经度
         * @apiSuccess (Store) {String} store_latitude 纬度
         */

        @importStore: function(ouid, { number, name, country, province, city, district, address, latitude, longitude, business_hours, image_url, manager_id, manager_account, manager_password, phone }) {

            if (!number) {
                throw @lab.errors.invalid_parameters
            }

            return lab.snapshot(function(snapshot) {

                return snapshot.find("slime_stores", {
                    "store_number": number,
                    "ouid": ouid
                }).then(function(searchResult) {

                    let existing_store;
                    let newStore;

                    if (searchResult) {
                        existing_store = searchResult;
                    } else {
                        existing_store = {
                            "id": @.uuid(),
                            "ouid": ouid,
                            "store_number": number,
                            "create_date": Date.now()
                        }
                        newStore = true;
                    }

                    let storeData = {};

                    if (!name && newStore) {
                        throw @lab.errors.invalid_parameters
                    }

                    storeData["store_name"] = name;

                    storeData["store_country"] = country;
                    storeData["store_province"] = province;
                    storeData["store_city"] = city;

                    storeData["store_district"] = district;
                    storeData["store_address"] = address;

                    storeData["store_latitude"] = latitude;
                    storeData["store_longitude"] = longitude;

                    storeData["store_business_hours"] = business_hours
                    storeData["store_image_url"] = image_url

                    storeData["store_phone"] = phone

                    storeData["last_update"] = Date.now();


                    if (storeData.store_latitude && storeData.store_longitude) {
                        storeData.store_geo_hash = GeoHash.encodeGeoHash(storeData.store_latitude, storeData.store_longitude);
                    }
                    
                    @.async(function() {

                        if (manager_id) {
                            snapshot.find("backend_operators", {
                                id: manager_id,
                                ouid: ouid
                            }).then(function(backend_manager) {
                                if (backend_manager) {
                                    this.next(backend_manager);
                                } else {
                                    throw @lab.errors.object_not_found;
                                }
                            }).pipe(this);
                        } else if (manager_account && manager_password) {

                            manager_account = manager_account.trim();
                            manager_password = manager_password.trim();

                            snapshot.find("backend_operators", {
                                account: manager_account
                            }).then(function(exist_operator) {
                                if (exist_operator) {

                                    if (exist_operator.ouid == ouid) {

                                        if (exist_operator.password != crypto.createHash('sha256').update(manager_password + exist_operator.salt).digest().toString("base64")) {
                                            @warn(`manager operator [${manager_account}] for store ${name},  password is invalid`);
                                        }

                                        this.next(exist_operator);
                                    } else {
                                        throw @lab.errors.object_not_found;
                                    }

                                } else {

                                    @info(`register manager operator [${manager_account}] for store ${name}`);

                                    lab.backend.users.@register({
                                        name,
                                        account: manager_account,
                                        password: manager_password,
                                        ouid: ouid,
                                        is_bot: false,
                                        access: []
                                    }).then(function({ user }) {
                                        this.next(user);
                                    }).pipe(this);
                                }

                            }).pipe(this);
                        } else {
                            this.next();
                        }

                    }).then(function(manager) {

                        if (manager) {
                            storeData["manager_id"] = manager.id;
                        }

                        if (searchResult) {
                            snapshot.update("slime_stores", existing_store, storeData).pipe(this);
                        } else {
                            snapshot.create("slime_stores", @.merge.simple(existing_store, storeData)).pipe(this);
                        }

                    }).then(function(savedStore) {

                        @mew.auto("slime.store.importStore", savedStore)

                        this.next(savedStore);

                        // if (trader_number) {

                        //     snapshot.sqlite.find("slime_traders", {
                        //         "ouid": ouid,
                        //         "trader_number": trader_number
                        //     }).then(function(result) {
                        //         if (result.records.length) {
                        //             this.next(result.records[0])
                        //         } else {
                        //             throw @lab.errors.object_not_found;
                        //         }
                        //     }).then(function(bingingTrader) {

                        //         snapshot.slime.store.@buildTraderRelationWithStore(ouid, {bingingTrader, savedStore}).pipe(this)

                        //     }).resolve(savedStore).pipe(this)

                        // } else {
                        //     this.next(savedStore);
                        // }

                    }).pipe(this)
                })
            })
        },
        /**
         * @api {jsonrpc} slime@store.searchStores(form)=result slime@store.searchStores
         * @apiDescription 搜索门店信息
         * @apiGroup slime
         * @apiParam (form) {Number} [start=0] 分页开始
         * @apiParam (form) {Number} [limit=10] 分页最大
         * @apiParam (form) {String} keyword 门店名称或门店编码
         * @apiParam (form) {String} trader_id 经销商id
         *
         * @apiSuccess {Object} result 门店信息
         * @apiUse TypeDefineStore
         */
        searchStores: function(session, { start = 0, limit = 10, keyword, trader_id }) {

            if (!session.currentOU) {
                throw @lab.errors.not_login;
            }

            let conditions = ["a.ouid = ?", "a.is_removed = ?"];
            let params = [session.currentOU.id, false];

            let models = ["slime_stores as a"];
            let fields = [];

            if (keyword) {
                conditions.push("(a.store_name like ? or a.store_number like ?)");
                params.push("%" + keyword + "%", "%" + keyword + "%");
            }

            if (trader_id) {

                models.push("left join slime_trader_stores as b on b.store_id = a.id");
                fields.push("a.*");

                condition.push("b.trader_id = ?");
                params.push(trader_id);

            }

            return lab.query(models, {
                "fields": fields,
                "conditions": conditions,
                "params": params,
                "start": start,
                "limit": limit
            })
        },
        getStore: function(session, id) {
            if (!session.currentOU) {
                throw @lab.errors.not_login;
            }
            return lab.find("slime_stores", {
                id,
                ouid: session.currentOU.id
            })
        },
        createStore: function(session, { number, name }) {
            if (!session.currentOU || !session.currentUser) {
                throw @lab.errors.not_login;
            }
            if (!number) {
                throw @lab.errors.invalid_parameters
            }
            return lab.snapshot(function(snapshot) {

                return snapshot.find("slime_stores", {
                    "store_number": number,
                    "ouid": session.currentOU.id,
                    "is_removed": false
                }).then(function(existing_store) {
                    if (existing_store) {
                        throw @lab.errors.object_existing
                    }
                    return snapshot.create("slime_stores", {
                        id: @.uuid(),
                        ouid: session.currentOU.id,
                        store_number: number,
                        store_name: name,
                        is_removed: false
                    }).then(function(result) {
                        @mew.auto("lab.add_operator_log", {
                            currentUser: session.currentUser,
                            target: result,
                            target_id: result.id,
                            method: "deleteStore",
                            kitty: "slime.store",
                            type: "门店操作",
                            message: `创建门店 ${result.store_name} `
                        })
                        this.next(result);
                    })
                })
            })
        },
        deleteStore: function(session, id) {
            if (!session.currentOU || !session.currentUser) {
                throw @lab.errors.not_login;
            }
            return lab.find("slime_stores", {
                id,
                ouid: session.currentOU.id
            }).then(function(result) {
                if (result) {
                    result.is_removed = true
                    @mew.auto("lab.add_operator_log", {
                        currentUser: session.currentUser,
                        target: {},
                        target_id: result.id,
                        method: "deleteStore",
                        kitty: "slime.store",
                        type: "门店操作",
                        message: `删除门店 ${result.store_name} `
                    })
                    return lab.update("slime_stores", result)
                } else {
                    this.next()
                }
            })
        },
        updateStore: function(session, form) {
            if (!session.currentOU || !session.currentUser) {
                throw @lab.errors.not_login;
            }
            return lab.find("slime_stores", form.id).then(function(result) {
                if (result) {
                    let message = "";
                    let item = {
                        "store_number": "门店编号",
                        "store_name": "门店名称",
                        "store_country": "国家",
                        "store_province": "省份",
                        "store_city": "城市",
                        "store_district": "区",
                        "store_address": "地址",
                        "store_latitude": "纬度",
                        "store_longitude": "经度",
                        "store_business_hours": "营业时间",
                        "store_image_url": "门店图片",
                        "store_phone": "门店电话"
                    }
                    let object_item = {
                        "store_kv_list": "门店KV",
                        "store_service_list": "服务列表",
                        "store_tip_list": "推荐列表"
                    }
                    @.keys(item).forEach(function(key) {
                        if (!@.is.nil(form[key]) && result[key] !== form[key]) {
                            message += `${item[key]} 从 ${result[key]} 变更为 ${form[key]}\n`
                            result[key] = form[key]
                        }
                    })
                    @.keys(object_item).forEach(function(key) {
                        if (!@.is.nil(form[key]) && JSON.stringify(result[key]) !== JSON.stringify(form[key])) {
                            message += `修改了 ${object_item[key]} \n`
                            result[key] = form[key]
                        }
                    })
                    if (message) {
                        result.last_update = Date.now()
                        @mew.auto("slime.store.importStore", result)
                        @mew.auto("lab.add_operator_log", {
                            currentUser: session.currentUser,
                            target: result,
                            target_id: result.id,
                            method: "updateStore",
                            kitty: "slime.store",
                            type: "门店操作",
                            message: `修改门店 ${result.store_name} ` + message
                        })
                        return lab.update("slime_stores", result)
                    } else {
                        this.next(result)
                    }
                } else {
                    throw @lab.errors.object_not_found
                }
            })
        },
        @buildTraderRelationWithStore: function(ouid, { bindingTrader, savedStore }) {

            return lab.snapshot(function(snapshot) {

                return snapshot.sqlite.find("slime_trader_stores", {
                    "ouid": ouid,
                    "store_id": savedStore.id,
                    "is_removed": false
                }).then(function(result) {

                    var doCreateAction = function() {

                        return snapshot.sqlite.find("slime_trader_stores", {
                            "ouid": ouid,
                            "store_id": savedStore.id,
                            "trader_id": bindingTrader ? bindingTrader.id : ouid,
                        }).then(function(existing_result) {

                            if (existing_result.records.length) {

                                snapshot.update("slime_trader_stores", existing_result.records[0], {
                                    "is_removed": false
                                }).pipe(this);

                            } else {

                                snapshot.create("slime_trader_stores", {
                                    "ouid": ouid,
                                    "store_id": savedStore.id,
                                    "trader_id": bindingTrader ? bindingTrader.id : ouid,
                                    "create_date": Date.now(),
                                    "is_removed": false
                                }).pipe(this);

                            }
                        });
                    };

                    // 建立关系
                    if (result.records.length) {

                        if (result.records[0].trader_id == bindingTrader.id) {

                            snapshot.update("slime_trader_stores", result.records[0], {
                                "is_removed": false
                            }).pipe(this);

                        } else {

                            snapshot.update("slime_trader_stores", result.records[0], {
                                "is_removed": false
                            }).then(function() {
                                doCreateAction().pipe(this);
                            }).pipe(this);

                        }


                    } else {

                        doCreateAction().pipe(this);

                    }

                });
            })
        }
    }
}